import { onMounted, nextTick } from 'vue'
import { CURRENT_CONFIG } from '@/api/http/config'
import { addTMap, jump } from '@/utils/cesium.utils'
import * as Cesium from 'cesium'
import {
  Camera,
  Cartesian3,
  Color,
  CustomDataSource,
  Ion,
  PolylineGlowMaterialProperty,
  Rectangle,
  ScreenSpaceEventHandler,
  ScreenSpaceEventType,
  Viewer
} from 'cesium'

type LineType = { Lon: number; Lat: number; height: number }
type Cesium3DTileset = Cesium.Cesium3DTileset & { customId?: string }
export class UseGMapManage {
  private viewer!: Viewer
  private Models: Cesium3DTileset[]
  constructor(private dataSource: CustomDataSource = new CustomDataSource('line')) {
    this.dataSource = dataSource
    this.Models = []
  }

  async initMap(container: string) {
    Ion.defaultAccessToken = CURRENT_CONFIG.defaultAccessToken
    Camera.DEFAULT_VIEW_RECTANGLE = Rectangle.fromDegrees(89.5, 20.4, 110.4, 61.2)
    this.viewer = new Viewer(container, {
      animation: false,
      timeline: false,
      baseLayerPicker: false, // 是否显示图层选择控件
      infoBox: false, // 信息框
      homeButton: false, // 显示默认的地图导航控制按钮
      navigationHelpButton: false, // 显示帮助信息按钮
      sceneModePicker: false, // 显示场景模式切换按钮
      selectionIndicator: false, // 显示选中指示器
      navigationInstructionsInitiallyVisible: false, // 导航说明控件是否显示
      geocoder: false,
      fullscreenButton: false, // 是否显示全屏按钮
      // terrainProvider: await Cesium.createWorldTerrainAsync(),
      shouldAnimate: true // 是否自动动画
    })

    const creditContainer = this.viewer.cesiumWidget.creditContainer as HTMLElement
    creditContainer!.style!.display = 'none'
    // 禁用地形
    this.viewer.scene.globe.depthTestAgainstTerrain = false
    // 禁用左键双击功能
    this.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    // this.map.viewer.scene.debugShowFramesPerSecond = import.meta.env.VITE_IS_PS!
    // 开启渲染帧率显示
    // this.map.viewer.scene.debugShowFramesPerSecond = false
    // 开启抗锯齿
    this.viewer.scene.postProcessStages.fxaa.enabled = false
    this.viewer.scene.debugShowFramesPerSecond = false
    const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(354759)
    // const classificationTileset = await Cesium.Cesium3DTileset.fromUrl('./terra_b3dms12/tileset.json', {
    //   // maximumScreenSpaceError: 64, // 用于驱动细节细化级别的最大屏幕空间错误;较高的值可提供更好的性能，但视觉质量较低。
    //   // skipLevelOfDetail: true, // 确定是否应在遍历期间应用详细级别跳过(默认false)
    //   // baseScreenSpaceError: 1024, // When skipLevelOfDetailis true，在跳过详细级别之前必须达到的屏幕空间错误(默认1024)
    //   // skipScreenSpaceErrorFactor: 1, // 定义要跳过的最小屏幕空间错误的乘数。与 一起使用skipLevels来确定要加载哪些图块(默认16)
    //   // skipLevels: 0, // skipLevelOfDetail是true 一个常量，定义了加载图块时要跳过的最小级别数。为 0 时，不跳过任何级别。与 一起使用skipScreenSpaceErrorFactor来确定要加载哪些图块。(默认1)
    //   // immediatelyLoadDesiredLevelOfDetail: true, // 当skipLevelOfDetail是时true，只会下载满足最大屏幕空间错误的图块。忽略跳过因素，只加载所需的图块(默认false)
    //   // loadSiblings: false, // 如果为true则不会在已加载完概况房屋后，自动从中心开始超清化房屋 --- 何时确定在遍历期间skipLevelOfDetail是否true始终下载可见瓦片的兄弟姐妹(默认false)
    //   // cullWithChildrenBounds: false, // 是否使用子边界体积的并集来剔除瓦片（默认true）
    //   // dynamicScreenSpaceError: true, // 减少距离相机较远的图块的屏幕空间错误(默认false)
    //   // dynamicScreenSpaceErrorDensity: 0.01, // 数值加大，能让周边加载变快 --- 用于调整动态屏幕空间误差的密度，类似于雾密度(默认0.00278)
    //   // dynamicScreenSpaceErrorFactor: 2.0, // 用于增加计算的动态屏幕空间误差的因素(默认4.0)
    //   // dynamicScreenSpaceErrorHeightFalloff: 0.25, // 密度开始下降的瓦片集高度的比率(默认0.25)
    // }).then(function (tileset) {
    //   console.log(tileset, 'tileset')
    //   const heightOffset = 0
    //   const boundingSphere = tileset.boundingSphere
    //   const cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
    //   console.log(cartographic, 'cartographic')
    //   const surface = Cesium.Cartesian3.fromRadians(
    //     cartographic.longitude,
    //     cartographic.latitude,
    //     0
    //   )
    //   const offset = Cesium.Cartesian3.fromRadians(
    //     cartographic.longitude,
    //     cartographic.latitude,
    //     heightOffset
    //   )
    //   const translation = Cesium.Cartesian3.subtract(
    //     offset,
    //     surface,
    //     new Cesium.Cartesian3()
    //   )
    //   tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)
    //   return tileset
    // })
    // console.log(classificationTileset, 'classificationTileset')
    //
    // this.viewer.scene.primitives.add(classificationTileset)

    // this.viewer.zoomTo(
    //   classificationTileset,
    //   new Cesium.HeadingPitchRange(0.5, -0.2, classificationTileset.boundingSphere.radius * 4.0),
    // )
    // 开启高程(需等待地形服务初始化完成)
    // viewer.terrainProvider = terrainProvider
    addTMap(this.viewer, 'img')
    addTMap(this.viewer, 'cva')
    // this.viewer.camera.flyTo({
    //   destination: Cesium.Cartesian3.fromDegrees(116.397428, 39.908826, 1000.0)
    // })
    this.viewer.dataSources.add(this.dataSource)
    // 开启点击事件
    this.viewer.screenSpaceEventHandler.setInputAction(({ position }: ScreenSpaceEventHandler.PositionedEvent) => {
      console.log(position, 'position')
      // 怎么判断点击到了模型上
      const pickedObject = this.viewer.scene.pick(position)
      console.log(pickedObject, 'pickedObject')
    }, ScreenSpaceEventType.LEFT_CLICK)
    return this.viewer
  }

  public getViewer() {
    return this.viewer
  }

  public globalPropertiesConfig() {
    const container = document.getElementById('g-container')
    if (container) {
      this.initMap('g-container')
    }
  }

  /**
   * @function 清除航线数据
   */
  public clearLine() {
    this.dataSource.entities.removeAll()
  }

  // 渲染一个航线数据
  public renderLine(data: LineType[]) {
    // 首先创建一个航线数据源
    console.log(this)

    this.dataSource.entities.removeAll()
    // 添加航线数据
    const dataMap = data.map((item) => [item.Lon, item.Lat, item.height])
    console.log(JSON.stringify(data.flatMap((item) => [item.Lon, item.Lat, item.height])), '========================')
    const positions = Cartesian3.fromDegreesArrayHeights(data.flatMap((item) => [item.Lon, item.Lat, item.height]))
    const dataLotAndLat = jump(dataMap)
    this.dataSource.entities.add({
      polyline: {
        positions: positions,
        width: 5,
        granularity: Cesium.Math.RADIANS_PER_DEGREE * 2,
        material: Cesium.Color.fromCssColorString('#5EF16B'),
        clampToGround: false, // 关键：禁用贴地[2]
      }
    })

    // 跳转到这个航线的起点
    this.viewer.camera.flyTo({
      destination: dataLotAndLat,
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: 0.0
      },
      duration: 1
    })
    data.forEach((item) => {
      this.dataSource.entities.add({
        position: Cartesian3.fromDegrees(item.Lon, item.Lat, item.height),
        point: {
          pixelSize: 10,
          color: Color.RED
        }
      })
      this.dataSource.entities.add({
        position: Cartesian3.fromDegrees(item.Lon, item.Lat, 0),
        point: {
          pixelSize: 6,
          color: Color.WHITE
        }
      })
      this.dataSource.entities.add({
        polyline: {
          positions: [Cartesian3.fromDegrees(item.Lon, item.Lat, item.height), Cartesian3.fromDegrees(item.Lon, item.Lat, 0)],
          width: 5,
          material: new PolylineGlowMaterialProperty({
            glowPower: 0.2,
            color: Color.WHITE
          })
        }
      })
    })
  }

  public async addModel(url: string, id: string) {
    // const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(354759)
    const classificationTileset = await Cesium.Cesium3DTileset.fromUrl(url)
    //  (classificationTileset as any).customId = id
    classificationTileset.customId = id
    console.log(classificationTileset, 'classificationTileset')
    this.viewer.scene.primitives.add(classificationTileset)
    this.Models.push(classificationTileset)
    console.log(this.Models, 'this.Models')
    // this.viewer.scene.primitives.add(tileset)
    this.viewer.zoomTo(
      classificationTileset,
      new Cesium.HeadingPitchRange(0.5, -0.2, classificationTileset.boundingSphere.radius * 4.0),
    )
  }

  // 获取所有的模型
  public getAllModels() {
    return this.Models
  }

  // 跳转到指定模型附件
  public flyToModel(id: string) {
    const target = this.Models.find((item) => item.customId === id)
    console.log(target, 'target')
    if (target) {
      const boundingSphere = target.boundingSphere.clone()
      const radius = boundingSphere.radius
      const center = boundingSphere.center
      const viewer = this.viewer
      viewer.camera.flyToBoundingSphere(boundingSphere, {
        offset: new Cesium.HeadingPitchRange(
          Cesium.Math.toRadians(0),
          Cesium.Math.toRadians(-90),
          radius * 4 // 保持1.5倍半径的安全距离
        ),
        duration: 1
      })
    }
  }

  // 使用示例：通过 ID 删除模型
  public removeModelById(id: string) {
    console.log(this.Models, '=================')
    this.Models.forEach((target) => {
      if (target.customId === id) {
        console.log(target, 'item')
        this.Models.splice(this.Models.indexOf(target), 1)
        this.viewer.scene.primitives.remove(target)
        console.log(this.Models, 'this.Models')
      }
    })
  }

  // 统一面的方法
  public initPolygon(PolygonLine: LineType[], Polygon: number[]) {
    console.log(PolygonLine, 'PolygonLine', Polygon)
    this.dataSource.entities.removeAll()
    this.renderPolygonLine(PolygonLine)
    this.renderPolygon(Polygon)
  }

  // 渲染面的线数据
  public renderPolygonLine(data: LineType[]) {
    // 添加航线数据
    const dataMap = data.map((item) => [item.Lon, item.Lat, item.height])
    // console.log(JSON.stringify(data.flatMap((item) => [item.Lon, item.Lat, item.height])))
    const positions = Cartesian3.fromDegreesArrayHeights(data.flatMap((item) => [item.Lon, item.Lat, item.height]))
    const dataLotAndLat = jump(dataMap)

    this.dataSource.entities.add({
      polyline: {
        positions: positions,
        width: 3,
        granularity: Cesium.Math.RADIANS_PER_DEGREE * 2,
        material: Cesium.Color.fromCssColorString('#5EF16B')
      }
    })

    // 跳转到这个航线的起点
    this.viewer.camera.flyTo({
      destination: dataLotAndLat,
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: 0.0
      },
      duration: 1
    })
  }

  // 渲染面的面数据
  public renderPolygon(data?: number[]) {
    console.log(data, '1=1==1111111111')

    this.dataSource.entities.add({
      polygon: {
        hierarchy: Cartesian3.fromDegreesArray([...data!]),
        material: Color.BLUE.withAlpha(0.5),
        // 添加边框
        outline: true,
        outlineColor: Color.WHITE,
        outlineWidth: 2,
        // 填充颜色
        fill: true,
      }
    })
  }

  /**
   *  添加图标公共函数
   *
   */
  addIcon({ right, src, title }: { right: string; src: string; title: string }) {
    const customWidgetContainer = document.createElement('img')
    customWidgetContainer.style.position = 'absolute'
    customWidgetContainer.style.top = '10px'
    customWidgetContainer.style.right = right || '90px'
    customWidgetContainer.style.zIndex = '1000'
    customWidgetContainer.className = 'cesium-geocoder-searchButton'
    customWidgetContainer.src = src
    customWidgetContainer.title = title
    this.viewer.container.appendChild(customWidgetContainer)
    return customWidgetContainer
  }

  /** 第一视角 */
  firstView(b: boolean) {
    const shipModel = this.viewer.entities.getById('shipModel')

    if (b && shipModel) {
      this.viewer.trackedEntity = shipModel
      // // 设置摄像机飞行到特定位置和方向
      // this.viewer.camera.flyTo({
      //   destination: Cesium.Cartesian3.fromElements(shipModel!.position!.x, shipModel!.position!.y, shipModel!.position!.z + 1000), // 增加高度以调整距离
      //   orientation: {
      //     heading: Cesium.Math.toRadians(0), // 方向：北
      //     pitch: Cesium.Math.toRadians(-90), // 俯仰：垂直向下
      //     roll: 0
      //   },
      //   duration: 2 // 飞行动画持续时间，单位秒
      // })
    } else {
      this.viewer.trackedEntity = undefined
    }
  }
}
export default new UseGMapManage()
